package com.tedu.API.io;

import org.junit.Test;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * RandomAccesFile解决：File无法实现读写操作
 *
 * RandomAccessFile类   随机访问文件类
 * 功能：实现“文件”、文件夹的读写操作，底层使用C语言，底层：二进制数据
 *
 * 创建随机访问文件类
 * RandomAccessFile   raf=new RandomAccessFile(”路径+文件全称“,"rw");
 * RandomAccessFile  rsf=new RandomAccessFile("路径+文件全称","r")
 * 第二个参数[mode 模式]：r 模式 --->该文件可以读操作
 *                     rw 模式--->该文件可以写操作
 * 需求：实现 CV    复制音乐/视频
 */
public class RandomAccessFileAPI {
    @Test
    public void testRAF() throws IOException {
        //RandomAccessFile对象创建出来---路径+全称  | 模式：”rw“
        RandomAccessFile raf=new RandomAccessFile("raf.txt","rw");
        //1.在API 项目文件夹下 创建raf.txt 文件，并且实现读写操作

        //计算机 识别：二进制    0000 0000
        /**
         * 需要往raf.txt 写一个 a 字母
         * write(整数：十进制)  十进制转换为计算机可以识别的二进制
         *       范围：0~255   ASCII码   二进制 ---十进制---字母
         *                                         97    a
         *                                         98    b
         *                                         101   e
         * 作用：往文件中写入一个字节,抛出IO流异常，存在写出失败情况
         *      整数的低八位写出到文件中
         *      1字节==8位二进制      0000 0001        1
         *                          0000 0010        2
         *                          0000 0011        3
         *
         *      1024字节==1KB
         *      1024KB==1MB
         *      1024MB==1G
         *      1024G==1T
         */
        raf.write(97);  //写出：一个字节，识别二进制，写十进制转二进制
        raf.write(98);
        raf.write(101);
        //write方法---一个字节一个字节写出
        //关闭流     close()
        raf.close();
    }

    /**
     * read()
     * 作用：读取一个字节，返回十进制 int类型返回，如果文件读到-1，代表结束
     *       存在IO流异常：读取可能失败~~
     */
    @Test
    public void testRead() throws IOException {
        //创建对象：随机访问文件对象---只读----raf.txt文件的内容
        RandomAccessFile raf=new RandomAccessFile("raf.txt","r");
        int i=raf.read();// "a"---ASCII码---97
        int j=raf.read();// "b"---ASCII码---98
        int k=raf.read();// ”e“---ASCII码---101
        int y=raf.read();// -1 代表   文件没有数据
        System.out.println(i+" "+j+" "+k+" "+y);
    }
    /**
     * RAF类---构造器实现：读写操作---write(数值)   read() 一个字节一个字母写出以及读入
     * 复制粘贴一个音乐  【version 1--不考虑效率】
     */
    @Test
    public void testCV() throws IOException {
        //1.源文件---”小跳蛙.mp3"---复制---操作：读入
        RandomAccessFile src=new RandomAccessFile("小跳蛙.mp3","r");
        //2.复制源文件---“新跳蛙.mp3"--粘贴---操作：写出
        RandomAccessFile desc=new RandomAccessFile("新跳蛙.mp3","rw");
        //3.用于保存读取到的字节：   ①保存一个字节  ②-1代表文件读取到末尾
        int data=-1;
        //4.一直 从”小跳蛙.mp3"中一个字节一个字节读取---[true]
        //同时一个字节一个字节写出“新跳蛙.mp3"
        //(data=src.read())!=-1          条件判断语句[true]
        long start=System.currentTimeMillis();
        while((data=src.read())!=-1){
            //同时一个字节一个字节写出”新跳蛙.mp3"
            desc.write(data);
        }
        long end=System.currentTimeMillis();
        System.out.println("复制粘贴花费多少："+(end-start)/1000+"秒");
    }
    /**
     * 需求：复制粘贴一个1音乐    【version  1--考虑效率】
     * 一个字节一个字节的读取---一个字节一个字节写出【慢】
     * 100KB读取----100KB写出    【快】
     */
    @Test
    public void testCVS() throws IOException {
        //1.从API目录下“小跳蛙.mp3"---读入数据【100KB】
        RandomAccessFile src=new RandomAccessFile("小跳蛙.mp3","r");
        //2.从API目录下写出”效率高.mp3"---写出
        RandomAccessFile desc=new RandomAccessFile("效率高.mp3","rw");
        //3.保存每一次读取的字节量: ①覆盖：保存读写的数据，保障数据稳定
        //                      ②没有数据：表示文件读取到末尾
        int len=-1;
         //4.效率：100KB     字节数组： byte
        byte[] data=new byte[1024*100]; //100KB
        //5.一直  从src文件中读取数据：100KB  | read(byte[] b)读取一个字节 读100KB
        //5.1 src.read()      从src"小跳蛙.mp3"一个一个字节的读
        //5.2 src.read(byte[] data)  从src"小跳蛙.mp3"  100KB的读
        //5.3 len=src.read(byte[] data)  保存从src"小跳蛙.mp3" 100KB的读
        //5.4(len=src.read(byte[] data))!=-1   【复制判断条件】
        //  将读到的100KB的字节数据保存len中，只要不等于-1，没有读完，一直读
        long start=System.currentTimeMillis();
        while (  (len=src.read(data)) !=-1 ){
            //  同时,读文件的同时，写出数据“效率高.mp3"文件
            //  write(整数)  写出一个字节【慢】
            //  write(字节数组,0,-1) 写出字节数组指定的单位量【例如：100KB】
            desc.write(data,0,len);
        }
        long end=System.currentTimeMillis();
        System.out.println("100KB复制版本："+(end-start)+"毫秒");
        //测：视频复制: 100KB
    }
    @Test
    public void testCV1() throws IOException {
        RandomAccessFile src=new RandomAccessFile("视频.mp4","r");
        RandomAccessFile desc=new RandomAccessFile("视频效率高.mp4","rw");
        int len1=-1;
        byte[] data=new byte[1024*100];
        long start=System.currentTimeMillis();
        while (  (len1=src.read(data)) !=-1 ) {
            desc.write(data, 0, len1);
        }
        long end=System.currentTimeMillis();
        System.out.println("100KB复制版本："+(end-start)+"毫秒");
        }
    }

